package org.ascollada.core
{
	import flash.errors.IllegalOperationError;
	
	import org.ascollada.core.ns.collada;
	
	public class DaeSource extends DaeElement
	{
		use namespace collada;
		
		/**
		 * 
		 */ 
		public var type :String;
		
		/**
		 * 
		 */ 
		public var data :Array;
		
		/**
		 * 
		 */ 
		public var accessor :DaeAccessor;
		
		/**
		 * Might be animated, if so this array will be set with an Array of DaeChannel
		 */ 
		public var channels :Array;
		
		/**
		 * 
		 */ 
		public function DaeSource(document:DaeDocument, element:XML=null)
		{
			super(document, element);
		}
		
		public override function read(element:XML):void
		{
			if(element.name().localName != "source")
			{
				throw new IllegalOperationError("DaeSource: expected a <source> element!");
			}
			
			super.read(element);
			
			if(element.float_array[0])
			{
				this.data = readStringArray(element.float_array[0]);
				this.type = "float_array";
			}
			else if(element.Name_array[0])
			{
				this.data = readStringArray(element.Name_array[0]);
				this.type = "Name_array";
			}
			else if(element.IDREF_array[0])
			{
				this.data = readStringArray(element.IDREF_array[0]);	
				this.type = "IDREF_array";
			}
			else if(element.bool_array[0])
			{
				this.data = readStringArray(element.bool_array[0]);
				this.type = "bool_array";
			}
			else if(element.int_array[0])
			{
				this.data = readStringArray(element.int_array[0]);
				this.type = "int_array";
			}
			else
			{
				throw new IllegalOperationError("DaeSource : no data found!");
			}
			
			// grab the accessor
			if(element..accessor[0])
			{
				this.accessor = new DaeAccessor(this.document, element..accessor[0]);
			}
			else
			{
				throw new IllegalOperationError("DaeSource : expected a single <accessor> element!");
			}
			
			var cnt :int = 0;
			var tmp :Array = new Array();
			for(var i:int = 0; i < this.accessor.count; i++)
			{
				var arr :Array = readValue(i, true);
				if(arr.length > 1)
					tmp.push(arr);
				else
					tmp.push(arr[0]);
			}
			this.data = tmp;
		}

		
		/**
		 * 
		 */ 
		public function readValue(index:int, forceType:Boolean=false):Array
		{
			var values :Array = new Array();
			var data :Array = this.data;
			var stride :int = this.accessor.stride;
			var type :String = this.type;
			var start :int = index * stride;
			var value :String;
			var i :int;
			
			for(i = 0; i < stride; i++)
			{
				value = data[start + i];
				if(forceType && (type == "bool_array" || type == "float_array" || type == "int_array"))
				{
					if(type == "float_array")
					{
						if(value.indexOf(",") != -1) 
						{
							value = value.replace(/,/, ".");
						}
						values.push(parseFloat(value));
					}
					else if(type == "bool_array")
					{
						values.push((value == "true" || value == "1" ? true : false));
					}
					else
					{
						values.push(parseInt(value, 10));
					}
				}
				else
				{
					values.push(value);	
				}
			}
			
			return values;
		}
	}
}